//cPaletteWindow.cpp
#include "cPaletteWindow.h"

/* Constructor with parent window.
 */
PaletteWindow::PaletteWindow(MainWindow *Parent)
{
	this->_Create(Parent);
}

/* PROTECTED: Internal constructor routine.
 */
void PaletteWindow::_Create(MainWindow *Parent)
{
	GtkWidget *MainBox, *EventBox;
	
	Window::_Create("Palettes", 256, 256);
	
	this->Parent = Parent;
	this->ShowGrid = true;
	
	//Connect signals
	gtk_signal_connect(GTK_OBJECT(this->GTKWin), "delete-event",
		(GtkSignalFunc)cPaletteWindow_DeleteEvent, this);
	
	
	//Main window box
    MainBox = gtk_vbox_new(FALSE, FALSE);
    gtk_container_add(GTK_CONTAINER(this->GTKWin), MainBox);
    
    
    //Event box for the drawing area
    EventBox = gtk_event_box_new();
    gtk_box_pack_start(GTK_BOX(MainBox), EventBox, TRUE, TRUE, 0);

    
    //The drawing area itself
    this->PaletteBox = new DrawBox(256, 272);
    
    this->PaletteBox->InstallConfigureCallback(
    	cPaletteWindow_PaletteBoxConfigureEvent, this, true);
    	
    this->PaletteBox->InstallExposeCallback(
    	cPaletteWindow_PaletteBoxExposeEvent, this, false);

	gtk_container_add(GTK_CONTAINER(EventBox),
		this->PaletteBox->GetDrawingArea());
	
	
	//Status label
	this->StatusLabel = GTK_LABEL(gtk_label_new("Ready."));
	gtk_misc_set_alignment(GTK_MISC(this->StatusLabel), 0, 0.5);
	gtk_box_pack_start(GTK_BOX(MainBox), GTK_WIDGET(this->StatusLabel),
		FALSE, FALSE, 0);
	
	gtk_widget_show_all(GTK_WIDGET(this->GTKWin));
}

/* Destructor.
 */
PaletteWindow::~PaletteWindow()
{
	if(this->GTKWin) gtk_widget_destroy(GTK_WIDGET(this->GTKWin));
}

/* Redraws the window.
 */
void PaletteWindow::Redraw()
{
	if(this->PaletteBox) this->PaletteBox->InvalidateAll();
}

/* Callback for palette DrawBox configure (resize, create etc) event.
 * Inputs:
 * -Box: The DrawBox.
 * -DrawingArea: The box's drawing area.
 * -Event: The event.
 * -Win: Pointer to the PaletteWindow the box belongs to.
 */
void cPaletteWindow_PaletteBoxConfigureEvent(DrawBox* Box,
GtkWidget* DrawingArea, GdkEventConfigure* Event, void *Win)
{
	Box->SetFGColour(0, 0, 0);
	Box->DrawRectangle(0, 0, 0, 0, true); //Clear
}

/* Callback for palette DrawBox expose (need repaint) event.
 * Inputs:
 * -Box: The DrawBox.
 * -DrawingArea: The box's drawing area.
 * -Event: The event.
 * -Win: Pointer to the PaletteWindow the box belongs to.
 */
void cPaletteWindow_PaletteBoxExposeEvent(DrawBox* Box, GtkWidget* DrawingArea,
GdkEventExpose* Event, void *Win)
{
	PaletteWindow *_this = (PaletteWindow*)Win;
	u16 Col;
	u8 R, G, B;
	
	if(!_this->Parent) return;
	Box->SetFGColour(0, 0, 0);
	Box->DrawRectangle(0, 0, 0, 0, true); //Clear
	
	//Draw palette
	for(u8 P = 0; P < 16; P++)
	{
		for(u8 C = 0; C < 16; C++)
		{
			Col = _this->Parent->CurrentLevel.GetColour(P, C);
			R = BITS(Col, 0, 4) << 3;
			G = BITS(Col, 5, 9) << 3;
			B = BITS(Col, 10, 14) << 3;
			Box->SetFGColour(R, G, B);
			Box->DrawRectangle(C * 16, P * 16, 16, 16, true);
		}
	}
	
	//Draw BG colour
	Box->SetFGColour(255, 255, 255);
	Box->DrawText(0, 258, "Background:");
	
	Col = _this->Parent->CurrentLevel.GetBGColour();
	R = BITS(Col, 0, 4) << 3;
	G = BITS(Col, 5, 9) << 3;
	B = BITS(Col, 10, 14) << 3;
	Box->SetFGColour(R, G, B);
	Box->DrawRectangle(81, 256, 15, 16, true);
	
	//Draw grid
	if(_this->ShowGrid)
	{
		Box->SetFGColour(64, 64, 64);
		for(u32 y=16; y<272; y += 16)
			Box->DrawLine(0, y, Box->GetWidth(), y);
		for(u32 x=16; x<256; x += 16)
			Box->DrawLine(x, 0, x, Box->GetHeight() - 16);
	}
}

/* FRIEND: Callback for delete_event (window was closed).
 * Inputs:
 * -Widget: Widget that received the event (i.e. the GTK Window).
 * -Event: The event.
 * -Win: The MainWindow object.
 * Returns: TRUE to stop other handlers, FALSE to propagate further.
 */
gboolean cPaletteWindow_DeleteEvent(GtkWidget *Widget, GdkEvent *Event, gpointer Win)
{
	PaletteWindow *_this = (PaletteWindow*)Win;
	if(_this->PaletteBox) delete(_this->PaletteBox); _this->PaletteBox = NULL;
	if(_this->GTKWin) gtk_widget_destroy(GTK_WIDGET(_this->GTKWin));
	_this->GTKWin = NULL;
	return TRUE;
}
